diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-08-03 09:14:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-03 09:14:35 (GMT) |
commit | 946a0b69e217ff22a6c056047eab42053e9a2d5f (patch) | |
tree | a06c9d04b4c2f82e4225d94253e54b827c2e9c0e /Python | |
parent | f08b2be4416163e3d18b8d09891e7cda0d8a21d4 (diff) | |
download | cpython-946a0b69e217ff22a6c056047eab42053e9a2d5f.zip cpython-946a0b69e217ff22a6c056047eab42053e9a2d5f.tar.gz cpython-946a0b69e217ff22a6c056047eab42053e9a2d5f.tar.bz2 |
[3.6] bpo-31071: Avoid masking original TypeError in call with * unpacking (GH-2957) (#2991)
when other arguments are passed.
(cherry picked from commit 25e4f77)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 770dfcb..8eb78bf 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -64,6 +64,8 @@ static void format_exc_unbound(PyCodeObject *co, int oparg); static PyObject * unicode_concatenate(PyObject *, PyObject *, PyFrameObject *, const _Py_CODEUNIT *); static PyObject * special_lookup(PyObject *, _Py_Identifier *); +static int check_args_iterable(PyObject *func, PyObject *vararg); +static void format_kwargs_mapping_error(PyObject *func, PyObject *kwargs); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -2578,14 +2580,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); if (none_val == NULL) { if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL && - PyErr_ExceptionMatches(PyExc_TypeError)) { - PyObject *func = PEEK(1 + oparg); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after * " - "must be an iterable, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - PEEK(i)->ob_type->tp_name); + PyErr_ExceptionMatches(PyExc_TypeError)) + { + check_args_iterable(PEEK(1 + oparg), PEEK(i)); } Py_DECREF(sum); goto error; @@ -2798,12 +2795,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (_PyDict_MergeEx(sum, arg, 2) < 0) { PyObject *func = PEEK(2 + oparg); if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - arg->ob_type->tp_name); + format_kwargs_mapping_error(func, arg); } else if (PyErr_ExceptionMatches(PyExc_KeyError)) { PyObject *exc, *val, *tb; @@ -3370,13 +3362,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) * is not a mapping. */ if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - func = SECOND(); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - kwargs->ob_type->tp_name); + format_kwargs_mapping_error(SECOND(), kwargs); } Py_DECREF(kwargs); goto error; @@ -3389,14 +3375,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) callargs = POP(); func = TOP(); if (!PyTuple_CheckExact(callargs)) { - if (Py_TYPE(callargs)->tp_iter == NULL && - !PySequence_Check(callargs)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after * " - "must be an iterable, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - callargs->ob_type->tp_name); + if (check_args_iterable(func, callargs) < 0) { Py_DECREF(callargs); goto error; } @@ -5351,6 +5330,32 @@ import_all_from(PyObject *locals, PyObject *v) return err; } +static int +check_args_iterable(PyObject *func, PyObject *args) +{ + if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after * " + "must be an iterable, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + args->ob_type->tp_name); + return -1; + } + return 0; +} + +static void +format_kwargs_mapping_error(PyObject *func, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + kwargs->ob_type->tp_name); +} + static void format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj) { |