@@ -4889,24 +4889,29 @@ fast_function(PyObject *func, PyObject **stack, int n, int nargs, int nk)
48894889}
48904890
48914891PyObject *
4892- _PyFunction_FastCall (PyObject * func , PyObject * * args , int nargs , PyObject * kwargs )
4892+ _PyFunction_FastCallDict (PyObject * func , PyObject * * args , int nargs ,
4893+ PyObject * kwargs )
48934894{
48944895 PyCodeObject * co = (PyCodeObject * )PyFunction_GET_CODE (func );
48954896 PyObject * globals = PyFunction_GET_GLOBALS (func );
48964897 PyObject * argdefs = PyFunction_GET_DEFAULTS (func );
48974898 PyObject * kwdefs , * closure , * name , * qualname ;
4899+ PyObject * kwtuple , * * k ;
48984900 PyObject * * d ;
48994901 int nd ;
4902+ Py_ssize_t nk ;
4903+ PyObject * result ;
49004904
49014905 PCALL (PCALL_FUNCTION );
49024906 PCALL (PCALL_FAST_FUNCTION );
49034907
4904- /* issue #27128: support for keywords will come later */
4905- assert (kwargs == NULL );
4908+ assert (kwargs == NULL || PyDict_Check (kwargs ));
49064909
4907- if (co -> co_kwonlyargcount == 0 && kwargs == NULL &&
4910+ if (co -> co_kwonlyargcount == 0 &&
4911+ (kwargs == NULL || PyDict_Size (kwargs ) == 0 ) &&
49084912 co -> co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE ))
49094913 {
4914+ /* Fast paths */
49104915 if (argdefs == NULL && co -> co_argcount == nargs ) {
49114916 return _PyFunction_FastCallNoKw (co , args , nargs , globals );
49124917 }
@@ -4920,6 +4925,30 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
49204925 }
49214926 }
49224927
4928+ if (kwargs != NULL ) {
4929+ Py_ssize_t pos , i ;
4930+ nk = PyDict_Size (kwargs );
4931+
4932+ kwtuple = PyTuple_New (2 * nk );
4933+ if (kwtuple == NULL ) {
4934+ return NULL ;
4935+ }
4936+
4937+ k = & PyTuple_GET_ITEM (kwtuple , 0 );
4938+ pos = i = 0 ;
4939+ while (PyDict_Next (kwargs , & pos , & k [i ], & k [i + 1 ])) {
4940+ Py_INCREF (k [i ]);
4941+ Py_INCREF (k [i + 1 ]);
4942+ i += 2 ;
4943+ }
4944+ nk = i / 2 ;
4945+ }
4946+ else {
4947+ kwtuple = NULL ;
4948+ k = NULL ;
4949+ nk = 0 ;
4950+ }
4951+
49234952 kwdefs = PyFunction_GET_KW_DEFAULTS (func );
49244953 closure = PyFunction_GET_CLOSURE (func );
49254954 name = ((PyFunctionObject * )func ) -> func_name ;
@@ -4933,11 +4962,14 @@ _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg
49334962 d = NULL ;
49344963 nd = 0 ;
49354964 }
4936- return _PyEval_EvalCodeWithName ((PyObject * )co , globals , (PyObject * )NULL ,
4937- args , nargs ,
4938- NULL , 0 ,
4939- d , nd , kwdefs ,
4940- closure , name , qualname );
4965+
4966+ result = _PyEval_EvalCodeWithName ((PyObject * )co , globals , (PyObject * )NULL ,
4967+ args , nargs ,
4968+ k , (int )nk ,
4969+ d , nd , kwdefs ,
4970+ closure , name , qualname );
4971+ Py_XDECREF (kwtuple );
4972+ return result ;
49414973}
49424974
49434975static PyObject *
0 commit comments