diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-08-22 21:15:44 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-08-22 21:15:44 (GMT) |
commit | b9009391868f739f4ddf09fa04061f6af05228b3 (patch) | |
tree | 984b506935ee9ce653cc7dd1268934e412639dac /Python | |
parent | 559bb6a71399af3b1b2a0ba97230d2bcc649e993 (diff) | |
download | cpython-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.c | 50 |
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 * |