From 5abaa2b139fb75a76933fb5437e09021fd080fae Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 9 Dec 2016 16:22:32 +0100 Subject: [PATCH] Use PyObject_CallFunctionObjArgs() Issue #28915: Replace PyObject_CallFunction() with PyObject_CallFunctionObjArgs() when the format string was only made of "O" formats, PyObject* arguments. PyObject_CallFunctionObjArgs() avoids the creation of a temporary tuple and doesn't have to parse a format string. --- Modules/_elementtree.c | 22 ++++++++++++++-------- Objects/abstract.c | 2 +- Objects/descrobject.c | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 8678c0a3701..ba827e667f6 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2496,11 +2496,13 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, attrib = PyDict_New(); if (!attrib) return NULL; - node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); Py_DECREF(attrib); } else { - node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); } if (!node) { return NULL; @@ -2977,7 +2979,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, return; } } - res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); + res = PyObject_CallFunctionObjArgs(self->handle_start, + tag, attrib, NULL); } else res = NULL; @@ -3143,8 +3146,9 @@ expat_start_doctype_handler(XMLParserObject *self, /* If the target has a handler for doctype, call it. */ if (self->handle_doctype) { - res = PyObject_CallFunction(self->handle_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); + res = PyObject_CallFunctionObjArgs(self->handle_doctype, + doctype_name_obj, pubid_obj, + sysid_obj, NULL); Py_CLEAR(res); } else { @@ -3163,8 +3167,9 @@ expat_start_doctype_handler(XMLParserObject *self, if (!res) goto clear; Py_DECREF(res); - res = PyObject_CallFunction(parser_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); + res = PyObject_CallFunctionObjArgs(parser_doctype, + doctype_name_obj, pubid_obj, + sysid_obj, NULL); Py_CLEAR(res); } } @@ -3191,7 +3196,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); if (target && data) { - res = PyObject_CallFunction(self->handle_pi, "OO", target, data); + res = PyObject_CallFunctionObjArgs(self->handle_pi, + target, data, NULL); Py_XDECREF(res); Py_DECREF(data); Py_DECREF(target); diff --git a/Objects/abstract.c b/Objects/abstract.c index 2c5057d133e..d3b9ec0d19c 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2549,7 +2549,7 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format, } if (nargs == 1 && PyTuple_Check(stack[0])) { - /* Special cases: + /* Special cases for backward compatibility: - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index ee356b1bf40..090c9cdd047 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1454,7 +1454,7 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) doc = pold->prop_doc ? pold->prop_doc : Py_None; } - new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); + new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL); Py_DECREF(type); if (new == NULL) return NULL;