diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2017-03-14 09:00:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-14 09:00:59 (GMT) |
commit | aa289a59ff6398110e1122877c073c9354ee53db (patch) | |
tree | 9861df74503cb7556be87ec43642efb5c4790748 /Objects/call.c | |
parent | 7e2a54cdd977078b40b82182e46b201f8163f659 (diff) | |
download | cpython-aa289a59ff6398110e1122877c073c9354ee53db.zip cpython-aa289a59ff6398110e1122877c073c9354ee53db.tar.gz cpython-aa289a59ff6398110e1122877c073c9354ee53db.tar.bz2 |
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.
Diffstat (limited to 'Objects/call.c')
-rw-r--r-- | Objects/call.c | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/Objects/call.c b/Objects/call.c index a4af816..f1b1408 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -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 * PyEval_CallFunction(PyObject *callable, const char *format, ...) { - 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; } @@ -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 * 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; } |