Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4d28d4

Browse files
committed
Issue #27809: partial_call() uses fast call for positional args
1 parent 1fa6915 commit f4d28d4

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

Modules/_functoolsmodule.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,44 +128,60 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kw)
128128
{
129129
PyObject *ret;
130130
PyObject *argappl, *kwappl;
131+
PyObject **stack;
132+
Py_ssize_t nargs;
131133

132134
assert (PyCallable_Check(pto->fn));
133135
assert (PyTuple_Check(pto->args));
134136
assert (PyDict_Check(pto->kw));
135137

136138
if (PyTuple_GET_SIZE(pto->args) == 0) {
137-
argappl = args;
138-
Py_INCREF(args);
139-
} else if (PyTuple_GET_SIZE(args) == 0) {
140-
argappl = pto->args;
141-
Py_INCREF(pto->args);
142-
} else {
139+
stack = &PyTuple_GET_ITEM(args, 0);
140+
nargs = PyTuple_GET_SIZE(args);
141+
argappl = NULL;
142+
}
143+
else if (PyTuple_GET_SIZE(args) == 0) {
144+
stack = &PyTuple_GET_ITEM(pto->args, 0);
145+
nargs = PyTuple_GET_SIZE(pto->args);
146+
argappl = NULL;
147+
}
148+
else {
149+
stack = NULL;
143150
argappl = PySequence_Concat(pto->args, args);
144-
if (argappl == NULL)
151+
if (argappl == NULL) {
145152
return NULL;
153+
}
154+
146155
assert(PyTuple_Check(argappl));
147156
}
148157

149158
if (PyDict_Size(pto->kw) == 0) {
150159
kwappl = kw;
151160
Py_XINCREF(kwappl);
152-
} else {
161+
}
162+
else {
153163
kwappl = PyDict_Copy(pto->kw);
154164
if (kwappl == NULL) {
155-
Py_DECREF(argappl);
165+
Py_XDECREF(argappl);
156166
return NULL;
157167
}
168+
158169
if (kw != NULL) {
159170
if (PyDict_Merge(kwappl, kw, 1) != 0) {
160-
Py_DECREF(argappl);
171+
Py_XDECREF(argappl);
161172
Py_DECREF(kwappl);
162173
return NULL;
163174
}
164175
}
165176
}
166177

167-
ret = PyObject_Call(pto->fn, argappl, kwappl);
168-
Py_DECREF(argappl);
178+
if (stack) {
179+
ret = _PyObject_FastCallDict(pto->fn, stack, nargs, kwappl);
180+
}
181+
else {
182+
ret = PyObject_Call(pto->fn, argappl, kwappl);
183+
Py_DECREF(argappl);
184+
}
169185
Py_XDECREF(kwappl);
170186
return ret;
171187
}

0 commit comments

Comments
 (0)