summaryrefslogtreecommitdiffstats
path: root/Modules/_functoolsmodule.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-08-23 14:22:35 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-08-23 14:22:35 (GMT)
commitf4d28d43857295cab4dc82a2bc50f5e8c90123ef (patch)
treeb8688a87548d5a536e1c967f084bdf961f8b3d33 /Modules/_functoolsmodule.c
parent1fa69154270c3ad41e8abfbc399128f31c41a63a (diff)
downloadcpython-f4d28d43857295cab4dc82a2bc50f5e8c90123ef.zip
cpython-f4d28d43857295cab4dc82a2bc50f5e8c90123ef.tar.gz
cpython-f4d28d43857295cab4dc82a2bc50f5e8c90123ef.tar.bz2
Issue #27809: partial_call() uses fast call for positional args
Diffstat (limited to 'Modules/_functoolsmodule.c')
-rw-r--r--Modules/_functoolsmodule.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 22e8088..848a03c 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -128,44 +128,60 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kw)
{
PyObject *ret;
PyObject *argappl, *kwappl;
+ PyObject **stack;
+ Py_ssize_t nargs;
assert (PyCallable_Check(pto->fn));
assert (PyTuple_Check(pto->args));
assert (PyDict_Check(pto->kw));
if (PyTuple_GET_SIZE(pto->args) == 0) {
- argappl = args;
- Py_INCREF(args);
- } else if (PyTuple_GET_SIZE(args) == 0) {
- argappl = pto->args;
- Py_INCREF(pto->args);
- } else {
+ stack = &PyTuple_GET_ITEM(args, 0);
+ nargs = PyTuple_GET_SIZE(args);
+ argappl = NULL;
+ }
+ else if (PyTuple_GET_SIZE(args) == 0) {
+ stack = &PyTuple_GET_ITEM(pto->args, 0);
+ nargs = PyTuple_GET_SIZE(pto->args);
+ argappl = NULL;
+ }
+ else {
+ stack = NULL;
argappl = PySequence_Concat(pto->args, args);
- if (argappl == NULL)
+ if (argappl == NULL) {
return NULL;
+ }
+
assert(PyTuple_Check(argappl));
}
if (PyDict_Size(pto->kw) == 0) {
kwappl = kw;
Py_XINCREF(kwappl);
- } else {
+ }
+ else {
kwappl = PyDict_Copy(pto->kw);
if (kwappl == NULL) {
- Py_DECREF(argappl);
+ Py_XDECREF(argappl);
return NULL;
}
+
if (kw != NULL) {
if (PyDict_Merge(kwappl, kw, 1) != 0) {
- Py_DECREF(argappl);
+ Py_XDECREF(argappl);
Py_DECREF(kwappl);
return NULL;
}
}
}
- ret = PyObject_Call(pto->fn, argappl, kwappl);
- Py_DECREF(argappl);
+ if (stack) {
+ ret = _PyObject_FastCallDict(pto->fn, stack, nargs, kwappl);
+ }
+ else {
+ ret = PyObject_Call(pto->fn, argappl, kwappl);
+ Py_DECREF(argappl);
+ }
Py_XDECREF(kwappl);
return ret;
}