@@ -2513,14 +2513,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
25132513 TARGET (BUILD_LIST_UNPACK ) {
25142514 int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK ;
25152515 Py_ssize_t i ;
2516- PyObject * sum ;
2516+ PyObject * sum = PyList_New ( 0 ) ;
25172517 PyObject * return_value ;
25182518
2519- if (convert_to_tuple && oparg == 1 && PyTuple_CheckExact (TOP ())) {
2520- DISPATCH ();
2521- }
2522-
2523- sum = PyList_New (0 );
25242519 if (sum == NULL )
25252520 goto error ;
25262521
@@ -2708,13 +2703,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
27082703 TARGET (BUILD_MAP_UNPACK ) {
27092704 int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL ;
27102705 Py_ssize_t i ;
2711- PyObject * sum ;
2712-
2713- if (with_call && oparg == 1 && PyDict_CheckExact (TOP ())) {
2714- DISPATCH ();
2715- }
2716-
2717- sum = PyDict_New ();
2706+ PyObject * sum = PyDict_New ();
27182707 if (sum == NULL )
27192708 goto error ;
27202709
@@ -3290,11 +3279,53 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
32903279 PCALL (PCALL_ALL );
32913280 if (oparg & 0x01 ) {
32923281 kwargs = POP ();
3282+ if (!PyDict_CheckExact (kwargs )) {
3283+ PyObject * d = PyDict_New ();
3284+ if (d == NULL )
3285+ goto error ;
3286+ if (PyDict_Update (d , kwargs ) != 0 ) {
3287+ Py_DECREF (d );
3288+ /* PyDict_Update raises attribute
3289+ * error (percolated from an attempt
3290+ * to get 'keys' attribute) instead of
3291+ * a type error if its second argument
3292+ * is not a mapping.
3293+ */
3294+ if (PyErr_ExceptionMatches (PyExc_AttributeError )) {
3295+ func = SECOND ();
3296+ PyErr_Format (PyExc_TypeError ,
3297+ "%.200s%.200s argument after ** "
3298+ "must be a mapping, not %.200s" ,
3299+ PyEval_GetFuncName (func ),
3300+ PyEval_GetFuncDesc (func ),
3301+ kwargs -> ob_type -> tp_name );
3302+ }
3303+ goto error ;
3304+ }
3305+ Py_DECREF (kwargs );
3306+ kwargs = d ;
3307+ }
32933308 assert (PyDict_CheckExact (kwargs ));
32943309 }
32953310 callargs = POP ();
3296- assert (PyTuple_CheckExact (callargs ));
32973311 func = TOP ();
3312+ if (!PyTuple_Check (callargs )) {
3313+ if (Py_TYPE (callargs )-> tp_iter == NULL &&
3314+ !PySequence_Check (callargs )) {
3315+ PyErr_Format (PyExc_TypeError ,
3316+ "%.200s%.200s argument after * "
3317+ "must be an iterable, not %.200s" ,
3318+ PyEval_GetFuncName (func ),
3319+ PyEval_GetFuncDesc (func ),
3320+ callargs -> ob_type -> tp_name );
3321+ goto error ;
3322+ }
3323+ Py_SETREF (callargs , PySequence_Tuple (callargs ));
3324+ if (callargs == NULL ) {
3325+ goto error ;
3326+ }
3327+ }
3328+ assert (PyTuple_Check (callargs ));
32983329
32993330 result = do_call_core (func , callargs , kwargs );
33003331 Py_DECREF (func );
@@ -3796,8 +3827,8 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
37963827static PyObject *
37973828_PyEval_EvalCodeWithName (PyObject * _co , PyObject * globals , PyObject * locals ,
37983829 PyObject * * args , Py_ssize_t argcount ,
3799- PyObject * * kws , Py_ssize_t kwcount ,
3800- PyObject * kwnames , PyObject * * kwstack ,
3830+ PyObject * * kwnames , PyObject * * kwargs ,
3831+ Py_ssize_t kwcount , int kwstep ,
38013832 PyObject * * defs , Py_ssize_t defcount ,
38023833 PyObject * kwdefs , PyObject * closure ,
38033834 PyObject * name , PyObject * qualname )
@@ -3811,9 +3842,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
38113842 const Py_ssize_t total_args = co -> co_argcount + co -> co_kwonlyargcount ;
38123843 Py_ssize_t i , n ;
38133844 PyObject * kwdict ;
3814- Py_ssize_t kwcount2 = kwnames == NULL ? 0 : PyTuple_GET_SIZE (kwnames );
3815-
3816- assert ((kwcount == 0 ) || (kws != NULL ));
38173845
38183846 if (globals == NULL ) {
38193847 PyErr_SetString (PyExc_SystemError ,
@@ -3873,11 +3901,12 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
38733901 }
38743902 }
38753903
3876- /* Handle keyword arguments passed as an array of (key, value) pairs */
3877- for (i = 0 ; i < kwcount ; i ++ ) {
3904+ /* Handle keyword arguments passed as two strided arrays */
3905+ kwcount *= kwstep ;
3906+ for (i = 0 ; i < kwcount ; i += kwstep ) {
38783907 PyObject * * co_varnames ;
3879- PyObject * keyword = kws [ 2 * i ];
3880- PyObject * value = kws [ 2 * i + 1 ];
3908+ PyObject * keyword = kwnames [ i ];
3909+ PyObject * value = kwargs [ i ];
38813910 Py_ssize_t j ;
38823911
38833912 if (keyword == NULL || !PyUnicode_Check (keyword )) {
@@ -3932,61 +3961,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
39323961 SETLOCAL (j , value );
39333962 }
39343963
3935- /* Handle keyword arguments passed as keys tuple + values array */
3936- for (i = 0 ; i < kwcount2 ; i ++ ) {
3937- PyObject * * co_varnames ;
3938- PyObject * keyword = PyTuple_GET_ITEM (kwnames , i );
3939- PyObject * value = kwstack [i ];
3940- int j ;
3941- if (keyword == NULL || !PyUnicode_Check (keyword )) {
3942- PyErr_Format (PyExc_TypeError ,
3943- "%U() keywords must be strings" ,
3944- co -> co_name );
3945- goto fail ;
3946- }
3947- /* Speed hack: do raw pointer compares. As names are
3948- normally interned this should almost always hit. */
3949- co_varnames = ((PyTupleObject * )(co -> co_varnames ))-> ob_item ;
3950- for (j = 0 ; j < total_args ; j ++ ) {
3951- PyObject * nm = co_varnames [j ];
3952- if (nm == keyword )
3953- goto kw_found2 ;
3954- }
3955- /* Slow fallback, just in case */
3956- for (j = 0 ; j < total_args ; j ++ ) {
3957- PyObject * nm = co_varnames [j ];
3958- int cmp = PyObject_RichCompareBool (
3959- keyword , nm , Py_EQ );
3960- if (cmp > 0 )
3961- goto kw_found2 ;
3962- else if (cmp < 0 )
3963- goto fail ;
3964- }
3965- if (j >= total_args && kwdict == NULL ) {
3966- PyErr_Format (PyExc_TypeError ,
3967- "%U() got an unexpected "
3968- "keyword argument '%S'" ,
3969- co -> co_name ,
3970- keyword );
3971- goto fail ;
3972- }
3973- if (PyDict_SetItem (kwdict , keyword , value ) == -1 ) {
3974- goto fail ;
3975- }
3976- continue ;
3977- kw_found2 :
3978- if (GETLOCAL (j ) != NULL ) {
3979- PyErr_Format (PyExc_TypeError ,
3980- "%U() got multiple "
3981- "values for argument '%S'" ,
3982- co -> co_name ,
3983- keyword );
3984- goto fail ;
3985- }
3986- Py_INCREF (value );
3987- SETLOCAL (j , value );
3988- }
3989-
39903964 /* Check the number of positional arguments */
39913965 if (argcount > co -> co_argcount && !(co -> co_flags & CO_VARARGS )) {
39923966 too_many_positional (co , argcount , defcount , fastlocals );
@@ -4138,8 +4112,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
41384112{
41394113 return _PyEval_EvalCodeWithName (_co , globals , locals ,
41404114 args , argcount ,
4141- kws , kwcount ,
4142- NULL , NULL ,
4115+ kws , kws + 1 , kwcount , 2 ,
41434116 defs , defcount ,
41444117 kwdefs , closure ,
41454118 NULL , NULL );
@@ -4923,8 +4896,9 @@ fast_function(PyObject *func, PyObject **stack,
49234896 }
49244897 return _PyEval_EvalCodeWithName ((PyObject * )co , globals , (PyObject * )NULL ,
49254898 stack , nargs ,
4926- NULL , 0 ,
4927- kwnames , stack + nargs ,
4899+ nkwargs ? & PyTuple_GET_ITEM (kwnames , 0 ) : NULL ,
4900+ stack + nargs ,
4901+ nkwargs , 1 ,
49284902 d , (int )nd , kwdefs ,
49294903 closure , name , qualname );
49304904}
@@ -5014,8 +4988,7 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
50144988
50154989 result = _PyEval_EvalCodeWithName ((PyObject * )co , globals , (PyObject * )NULL ,
50164990 args , nargs ,
5017- k , nk ,
5018- NULL , NULL ,
4991+ k , k + 1 , nk , 2 ,
50194992 d , nd , kwdefs ,
50204993 closure , name , qualname );
50214994 Py_XDECREF (kwtuple );
0 commit comments