Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit aa289a5

Browse files
authored
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.
1 parent 7e2a54c commit aa289a5

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

Include/ceval.h

+6
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

+24-33
Original file line numberDiff line numberDiff line change
@@ -940,25 +940,20 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...)
940940
}
941941

942942

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

958-
res = PyEval_CallObject(callable, args);
959-
Py_DECREF(args);
952+
va_start(va, format);
953+
result = _PyObject_CallFunctionVa(callable, format, va, 0);
954+
va_end(va);
960955

961-
return res;
956+
return result;
962957
}
963958

964959

@@ -1015,33 +1010,29 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
10151010
}
10161011

10171012

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

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

1035-
if (args == NULL) {
1036-
Py_DECREF(meth);
1026+
callable = PyObject_GetAttrString(obj, name);
1027+
if (callable == NULL)
10371028
return NULL;
1038-
}
10391029

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

1044-
return res;
1034+
Py_DECREF(callable);
1035+
return retval;
10451036
}
10461037

10471038

0 commit comments

Comments
 (0)