From 4a3c0d5cf36d98a8d474ba2737f25c841c048049 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Tue, 14 Feb 2017 02:14:31 +0900 Subject: [PATCH] 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. --- Include/ceval.h | 6 ++++++ Objects/call.c | 57 +++++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index e4be595469fc29..8760fe50b70d6a 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -7,6 +7,12 @@ extern "C" { /* Interface to random parts in ceval.c */ +/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction + * and PyEval_CallMethod are kept for backward compatibility: PyObject_Call(), + * PyObject_CallFunction() and PyObject_CallMethod() are recommended to call + * a callable object. + */ + PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( PyObject *callable, PyObject *args, diff --git a/Objects/call.c b/Objects/call.c index 310b4a205f3847..7cf3a2bc0438b8 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -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, ...) { - 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; } @@ -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; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy