Add _PyObject_CallFunctionVa() helper

Issue #28915: Add _PyObject_CallFunctionVa() helper to factorize code of
functions:

* PyObject_CallFunction()
* _PyObject_CallFunction_SizeT()
* callmethod()
This commit is contained in:
Victor Stinner 2016-12-09 00:22:56 +01:00
parent 3bb711998d
commit e83aab12b0
1 changed files with 52 additions and 77 deletions

View File

@ -2519,27 +2519,10 @@ _PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t narg
}
}
static PyObject*
call_function_tail(PyObject *callable, PyObject *args)
static PyObject *
_PyObject_CallFunctionVa(PyObject *callable, const char *format,
va_list va, int is_size_t)
{
PyObject *result;
assert(args != NULL);
if (!PyTuple_Check(args)) {
result = PyObject_CallFunctionObjArgs(callable, args, NULL);
}
else {
result = PyObject_Call(callable, args, NULL);
}
return result;
}
PyObject *
PyObject_CallFunction(PyObject *callable, const char *format, ...)
{
va_list va;
PyObject *args, *result;
if (callable == NULL) {
@ -2550,75 +2533,67 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...)
return _PyObject_CallNoArg(callable);
}
va_start(va, format);
args = Py_VaBuildValue(format, va);
va_end(va);
if (args == NULL) {
return NULL;
}
result = call_function_tail(callable, args);
Py_DECREF(args);
return result;
}
PyObject *
_PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
{
va_list va;
PyObject *args, *result;
if (callable == NULL) {
return null_error();
}
if (!format || !*format) {
return _PyObject_CallNoArg(callable);
}
va_start(va, format);
args = _Py_VaBuildValue_SizeT(format, va);
va_end(va);
if (args == NULL) {
return NULL;
}
result = call_function_tail(callable, args);
Py_DECREF(args);
return result;
}
static PyObject*
callmethod(PyObject* callable, const char *format, va_list va, int is_size_t)
{
PyObject *args, *result;
assert(callable != NULL);
if (!PyCallable_Check(callable)) {
type_error("attribute of type '%.200s' is not callable", callable);
return NULL;
}
if (!format || !*format) {
return _PyObject_CallNoArg(callable);
}
if (is_size_t) {
args = _Py_VaBuildValue_SizeT(format, va);
args = Py_VaBuildValue(format, va);
}
else {
args = Py_VaBuildValue(format, va);
args = _Py_VaBuildValue_SizeT(format, va);
}
if (args == NULL) {
return NULL;
}
result = call_function_tail(callable, args);
if (!PyTuple_Check(args)) {
PyObject *stack[1] = {args};
result = _PyObject_FastCall(callable, stack, 1);
}
else {
result = PyObject_Call(callable, args, NULL);
}
Py_DECREF(args);
return result;
}
PyObject *
PyObject_CallFunction(PyObject *callable, const char *format, ...)
{
va_list va;
PyObject *result;
va_start(va, format);
result = _PyObject_CallFunctionVa(callable, format, va, 0);
va_end(va);
return result;
}
PyObject *
_PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
{
va_list va;
PyObject *result;
va_start(va, format);
result = _PyObject_CallFunctionVa(callable, format, va, 1);
va_end(va);
return result;
}
static PyObject*
callmethod(PyObject* callable, const char *format, va_list va, int is_size_t)
{
assert(callable != NULL);
if (!PyCallable_Check(callable)) {
type_error("attribute of type '%.200s' is not callable", callable);
return NULL;
}
return _PyObject_CallFunctionVa(callable, format, va, is_size_t);
}
PyObject *
PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
{