diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-08-03 08:37:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-03 08:37:15 (GMT) |
commit | 25e4f779d7ae9f37a1933cb5cbfad06e673c01f9 (patch) | |
tree | cf3671f5eed00c26f2ccef0634ff4ce556aac286 /Python/ceval.c | |
parent | 49b2734bf12dc1cda80fd73d3ec8896ae3e362f2 (diff) | |
download | cpython-25e4f779d7ae9f37a1933cb5cbfad06e673c01f9.zip cpython-25e4f779d7ae9f37a1933cb5cbfad06e673c01f9.tar.gz cpython-25e4f779d7ae9f37a1933cb5cbfad06e673c01f9.tar.bz2 |
bpo-31071: Avoid masking original TypeError in call with * unpacking (#2957)
when other arguments are passed.
Diffstat (limited to 'Python/ceval.c')
-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 be5cda5..9f732f5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -66,6 +66,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" @@ -2512,14 +2514,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; @@ -2732,12 +2729,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; @@ -3390,13 +3382,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; @@ -3409,14 +3395,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; } @@ -5179,6 +5158,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) { |