summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-08-22 21:15:44 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-08-22 21:15:44 (GMT)
commitb9009391868f739f4ddf09fa04061f6af05228b3 (patch)
tree984b506935ee9ce653cc7dd1268934e412639dac /Python
parent559bb6a71399af3b1b2a0ba97230d2bcc649e993 (diff)
downloadcpython-b9009391868f739f4ddf09fa04061f6af05228b3.zip
cpython-b9009391868f739f4ddf09fa04061f6af05228b3.tar.gz
cpython-b9009391868f739f4ddf09fa04061f6af05228b3.tar.bz2
_PyFunction_FastCallDict() supports keyword args
Issue #27809: * Rename _PyFunction_FastCall() to _PyFunction_FastCallDict() * Rename _PyCFunction_FastCall() to _PyCFunction_FastCallDict() * _PyFunction_FastCallDict() now supports keyword arguments
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 96380bc..d656fab 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4889,24 +4889,29 @@ fast_function(PyObject *func, PyObject **stack, int n, int nargs, int nk)
}
PyObject *
-_PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs)
+_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs,
+ PyObject *kwargs)
{
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
PyObject *kwdefs, *closure, *name, *qualname;
+ PyObject *kwtuple, **k;
PyObject **d;
int nd;
+ Py_ssize_t nk;
+ PyObject *result;
PCALL(PCALL_FUNCTION);
PCALL(PCALL_FAST_FUNCTION);
- /* issue #27128: support for keywords will come later */
- assert(kwargs == NULL);
+ assert(kwargs == NULL || PyDict_Check(kwargs));
- if (co->co_kwonlyargcount == 0 && kwargs == NULL &&
+ if (co->co_kwonlyargcount == 0 &&
+ (kwargs == NULL || PyDict_Size(kwargs) == 0) &&
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
{
+ /* Fast paths */
if (argdefs == NULL && co->co_argcount == nargs) {
return _PyFunction_FastCallNoKw(co, args, nargs, globals);
}
@@ -4920,6 +4925,30 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
}
}
+ if (kwargs != NULL) {
+ Py_ssize_t pos, i;
+ nk = PyDict_Size(kwargs);
+
+ kwtuple = PyTuple_New(2 * nk);
+ if (kwtuple == NULL) {
+ return NULL;
+ }
+
+ k = &PyTuple_GET_ITEM(kwtuple, 0);
+ pos = i = 0;
+ while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) {
+ Py_INCREF(k[i]);
+ Py_INCREF(k[i+1]);
+ i += 2;
+ }
+ nk = i / 2;
+ }
+ else {
+ kwtuple = NULL;
+ k = NULL;
+ nk = 0;
+ }
+
kwdefs = PyFunction_GET_KW_DEFAULTS(func);
closure = PyFunction_GET_CLOSURE(func);
name = ((PyFunctionObject *)func) -> func_name;
@@ -4933,11 +4962,14 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
d = NULL;
nd = 0;
}
- return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
- args, nargs,
- NULL, 0,
- d, nd, kwdefs,
- closure, name, qualname);
+
+ result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
+ args, nargs,
+ k, (int)nk,
+ d, nd, kwdefs,
+ closure, name, qualname);
+ Py_XDECREF(kwtuple);
+ return result;
}
static PyObject *