Commit aa289a59 authored by INADA Naoki's avatar INADA Naoki Committed by GitHub

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.
parent 7e2a54cd
...@@ -7,6 +7,12 @@ extern "C" { ...@@ -7,6 +7,12 @@ extern "C" {
/* Interface to random parts in ceval.c */ /* Interface to random parts in ceval.c */
/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction
* and PyEval_CallMethod are kept for backward compatibility: PyObject_Call(),
* PyObject_CallFunction() and PyObject_CallMethod() are recommended to call
* a callable object.
*/
PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords(
PyObject *callable, PyObject *callable,
PyObject *args, PyObject *args,
......
...@@ -940,25 +940,20 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...) ...@@ -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 * PyObject *
PyEval_CallFunction(PyObject *callable, const char *format, ...) PyEval_CallFunction(PyObject *callable, const char *format, ...)
{ {
va_list vargs; va_list va;
PyObject *args; PyObject *result;
PyObject *res;
va_start(vargs, format);
args = Py_VaBuildValue(format, vargs);
va_end(vargs);
if (args == NULL)
return NULL;
res = PyEval_CallObject(callable, args); va_start(va, format);
Py_DECREF(args); 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, ...) ...@@ -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 * PyObject *
PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...)
{ {
va_list vargs; va_list va;
PyObject *meth; PyObject *callable, *retval;
PyObject *args;
PyObject *res;
meth = PyObject_GetAttrString(obj, name);
if (meth == NULL)
return NULL;
va_start(vargs, format);
args = Py_VaBuildValue(format, vargs); if (obj == NULL || name == NULL) {
va_end(vargs); return null_error();
}
if (args == NULL) { callable = PyObject_GetAttrString(obj, name);
Py_DECREF(meth); if (callable == NULL)
return NULL; return NULL;
}
res = PyEval_CallObject(meth, args); va_start(va, format);
Py_DECREF(meth); retval = callmethod(callable, format, va, 0);
Py_DECREF(args); va_end(va);
return res; Py_DECREF(callable);
return retval;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment