◐ Shell
clean mode source ↗

bpo-29548: Recommend PyObject_Call APIs over PyEval_Call APIs. by methane · Pull Request #75 · python/cpython

Expand Up @@ -939,25 +939,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, ...)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commit message: this change also optimizes PyEval_CallFunction() and PyEval_CallMethod() to avoid temporary tuple when possible.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main purpose is reducing maintenance cost rather than optimization.
There are very few callers in the world.

I hope compiler can remove duplicated code too, but I'm not sure.

{ 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; }

Expand Down Expand Up @@ -1014,33 +1009,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; }

Expand Down