cpython: 1aefb4c4a7b4 (original) (raw)
Mercurial > cpython
changeset 102842:1aefb4c4a7b4
_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 [#27809]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Mon, 22 Aug 2016 23:15:44 +0200 |
parents | 263334a652ac |
children | 7924eac912fe |
files | Include/funcobject.h Include/methodobject.h Objects/abstract.c Objects/methodobject.c Python/ceval.c |
diffstat | 5 files changed, 52 insertions(+), 21 deletions(-)[+] [-] Include/funcobject.h 2 Include/methodobject.h 2 Objects/abstract.c 11 Objects/methodobject.c 6 Python/ceval.c 52 |
line wrap: on
line diff
--- a/Include/funcobject.h +++ b/Include/funcobject.h @@ -59,7 +59,7 @@ PyAPI_FUNC(PyObject *) PyFunction_GetAnn PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyFunction_FastCall( +PyAPI_FUNC(PyObject *) _PyFunction_FastCallDict( PyObject *func, PyObject **args, int nargs, PyObject *kwargs);
--- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -38,7 +38,7 @@ PyAPI_FUNC(int) PyCFunction_GetFlags(PyO PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyCFunction_FastCall(PyObject *func, +PyAPI_FUNC(PyObject *) _PyCFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs); #endif
--- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2255,7 +2255,8 @@ PyObject* } PyObject * -_PyObject_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) +_PyObject_FastCallDict(PyObject *func, PyObject **args, int nargs,
PyObject *kwargs)[](#l3.9)
{ ternaryfunc call; PyObject *result = NULL; @@ -2268,19 +2269,17 @@ PyObject * assert(func != NULL); assert(nargs >= 0); assert(nargs == 0 || args != NULL);
- /* issue #27128: support for keywords will come later:
_PyFunction_FastCall() doesn't support keyword arguments yet */[](#l3.18)
- assert(kwargs == NULL);
if (Py_EnterRecursiveCall(" while calling a Python object")) { return NULL; } if (PyFunction_Check(func)) {
result = _PyFunction_FastCall(func, args, nargs, kwargs);[](#l3.27)
} else if (PyCFunction_Check(func)) {result = _PyFunction_FastCallDict(func, args, nargs, kwargs);[](#l3.28)
result = _PyCFunction_FastCall(func, args, nargs, kwargs);[](#l3.31)
--- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -146,8 +146,8 @@ PyCFunction_Call(PyObject *func, PyObjec } PyObject * -_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, int nargs,
PyObject *kwargs)[](#l4.8)
+_PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, int nargs,
PyObject *kwargs)[](#l4.10)
{ PyCFunctionObject* func = (PyCFunctionObject*)func_obj; PyCFunction meth = PyCFunction_GET_FUNCTION(func); @@ -155,7 +155,7 @@ PyObject * PyObject *result; int flags;
- /* _PyCFunction_FastCallDict() must not be called with an exception set, because it may clear it (directly or indirectly) and so the caller loses its exception */ assert(!PyErr_Occurred());
--- a/Python/ceval.c +++ b/Python/ceval.c @@ -4889,24 +4889,29 @@ fast_function(PyObject *func, PyObject * } PyObject * -_PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) +_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs,
PyObject *kwargs)[](#l5.9)
{ PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); PyObject *kwdefs, *closure, *name, *qualname;
PCALL(PCALL_FUNCTION); PCALL(PCALL_FAST_FUNCTION);
- if (co->co_kwonlyargcount == 0 &&
{(kwargs == NULL || PyDict_Size(kwargs) == 0) &&[](#l5.31) co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))[](#l5.32)
/* Fast paths */[](#l5.34) if (argdefs == NULL && co->co_argcount == nargs) {[](#l5.35) return _PyFunction_FastCallNoKw(co, args, nargs, globals);[](#l5.36) }[](#l5.37)
@@ -4920,6 +4925,30 @@ PyObject * } }
kwtuple = PyTuple_New(2 * nk);[](#l5.46)
if (kwtuple == NULL) {[](#l5.47)
return NULL;[](#l5.48)
}[](#l5.49)
k = &PyTuple_GET_ITEM(kwtuple, 0);[](#l5.51)
pos = i = 0;[](#l5.52)
while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) {[](#l5.53)
Py_INCREF(k[i]);[](#l5.54)
Py_INCREF(k[i+1]);[](#l5.55)
i += 2;[](#l5.56)
}[](#l5.57)
nk = i / 2;[](#l5.58)
- }
- else {
kwtuple = NULL;[](#l5.61)
k = NULL;[](#l5.62)
nk = 0;[](#l5.63)
- }
+ kwdefs = PyFunction_GET_KW_DEFAULTS(func); closure = PyFunction_GET_CLOSURE(func); name = ((PyFunctionObject *)func) -> func_name; @@ -4933,11 +4962,14 @@ PyObject * d = NULL; nd = 0; }
- return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
args, nargs,[](#l5.74)
NULL, 0,[](#l5.75)
d, nd, kwdefs,[](#l5.76)
closure, name, qualname);[](#l5.77)