Skip to content

Commit 4a3c0d5

Browse files
committed
bpo-29548: Recommend PyObject_Call APIs over PyEval_Call APIs.
PyEval_Call* APIs are not documented and they doesn't respect PY_SSIZE_T_CLEAN. So add comment block to recommend PyObject_Call* APIs where they are declared. 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.
1 parent 43f5df5 commit 4a3c0d5

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

Include/ceval.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ extern "C" {
77

88
/* Interface to random parts in ceval.c */
99

10+
/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction
11+
* and PyEval_CallMethod are kept for backward compatibility: PyObject_Call(),
12+
* PyObject_CallFunction() and PyObject_CallMethod() are recommended to call
13+
* a callable object.
14+
*/
15+
1016
PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords(
1117
PyObject *callable,
1218
PyObject *args,

Objects/call.c

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -939,25 +939,20 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...)
939939
}
940940

941941

942+
/* PyEval_CallFunction is exact copy of PyObject_CallFunction.
943+
* This function is kept for backward compatibility.
944+
*/
942945
PyObject *
943946
PyEval_CallFunction(PyObject *callable, const char *format, ...)
944947
{
945-
va_list vargs;
946-
PyObject *args;
947-
PyObject *res;
948-
949-
va_start(vargs, format);
950-
951-
args = Py_VaBuildValue(format, vargs);
952-
va_end(vargs);
953-
954-
if (args == NULL)
955-
return NULL;
948+
va_list va;
949+
PyObject *result;
956950

957-
res = PyEval_CallObject(callable, args);
958-
Py_DECREF(args);
951+
va_start(va, format);
952+
result = _PyObject_CallFunctionVa(callable, format, va, 0);
953+
va_end(va);
959954

960-
return res;
955+
return result;
961956
}
962957

963958

@@ -1014,33 +1009,29 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
10141009
}
10151010

10161011

1012+
/* PyEval_CallMethod is exact copy of PyObject_CallMethod.
1013+
* This function is kept for backward compatibility.
1014+
*/
10171015
PyObject *
10181016
PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...)
10191017
{
1020-
va_list vargs;
1021-
PyObject *meth;
1022-
PyObject *args;
1023-
PyObject *res;
1024-
1025-
meth = PyObject_GetAttrString(obj, name);
1026-
if (meth == NULL)
1027-
return NULL;
1028-
1029-
va_start(vargs, format);
1018+
va_list va;
1019+
PyObject *callable, *retval;
10301020

1031-
args = Py_VaBuildValue(format, vargs);
1032-
va_end(vargs);
1021+
if (obj == NULL || name == NULL) {
1022+
return null_error();
1023+
}
10331024

1034-
if (args == NULL) {
1035-
Py_DECREF(meth);
1025+
callable = PyObject_GetAttrString(obj, name);
1026+
if (callable == NULL)
10361027
return NULL;
1037-
}
10381028

1039-
res = PyEval_CallObject(meth, args);
1040-
Py_DECREF(meth);
1041-
Py_DECREF(args);
1029+
va_start(va, format);
1030+
retval = callmethod(callable, format, va, 0);
1031+
va_end(va);
10421032

1043-
return res;
1033+
Py_DECREF(callable);
1034+
return retval;
10441035
}
10451036

10461037

0 commit comments

Comments
 (0)