Issue #28257: Improved error message when pass a non-mapping as a var-keyword

argument.
This commit is contained in:
Serhiy Storchaka 2016-10-07 23:32:41 +03:00
parent de0574bdab
commit 5665301bae
2 changed files with 27 additions and 4 deletions

View File

@ -269,6 +269,16 @@ not function
... ...
TypeError: h() argument after ** must be a mapping, not list TypeError: h() argument after ** must be a mapping, not list
>>> h(**{'a': 1}, **h)
Traceback (most recent call last):
...
TypeError: h() argument after ** must be a mapping, not function
>>> h(**{'a': 1}, **[])
Traceback (most recent call last):
...
TypeError: h() argument after ** must be a mapping, not list
>>> dir(**h) >>> dir(**h)
Traceback (most recent call last): Traceback (most recent call last):
... ...

View File

@ -2663,7 +2663,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
PyObject *intersection = _PyDictView_Intersect(sum, arg); PyObject *intersection = _PyDictView_Intersect(sum, arg);
if (intersection == NULL) { if (intersection == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) { if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
!PyMapping_Check(arg)) {
int function_location = (oparg>>8) & 0xff; int function_location = (oparg>>8) & 0xff;
PyObject *func = ( PyObject *func = (
PEEK(function_location + num_maps)); PEEK(function_location + num_maps));
@ -2707,10 +2708,22 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
if (PyDict_Update(sum, arg) < 0) { if (PyDict_Update(sum, arg) < 0) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
if (with_call) {
int function_location = (oparg>>8) & 0xff;
PyObject *func = PEEK(function_location + num_maps);
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);
}
else {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"'%.200s' object is not a mapping", "'%.200s' object is not a mapping",
arg->ob_type->tp_name); arg->ob_type->tp_name);
} }
}
Py_DECREF(sum); Py_DECREF(sum);
goto error; goto error;
} }