bpo-29548: Recommend PyObject_Call APIs over PyEval_Call APIs. by methane · Pull Request #75 · python/cpython
/* 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_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; }
/* 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; }