[Python-checkins] cpython (3.5): Issue #28257: Improved error message when pass a non-mapping as a var-keyword

serhiy.storchaka python-checkins at python.org
Fri Oct 7 16:35:21 EDT 2016


https://hg.python.org/cpython/rev/35676cd72352
changeset:   104358:35676cd72352
branch:      3.5
parent:      104354:5c459b0f2b75
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Fri Oct 07 23:32:41 2016 +0300
summary:
  Issue #28257: Improved error message when pass a non-mapping as a var-keyword
argument.

files:
  Lib/test/test_extcall.py |  10 ++++++++++
  Python/ceval.c           |  21 +++++++++++++++++----
  2 files changed, 27 insertions(+), 4 deletions(-)


diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py
--- a/Lib/test/test_extcall.py
+++ b/Lib/test/test_extcall.py
@@ -269,6 +269,16 @@
       ...
     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)
     Traceback (most recent call last):
       ...
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2663,7 +2663,8 @@
                     PyObject *intersection = _PyDictView_Intersect(sum, arg);
 
                     if (intersection == NULL) {
-                        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                        if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
+                            !PyMapping_Check(arg)) {
                             int function_location = (oparg>>8) & 0xff;
                             PyObject *func = (
                                     PEEK(function_location + num_maps));
@@ -2707,9 +2708,21 @@
 
                 if (PyDict_Update(sum, arg) < 0) {
                     if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-                        PyErr_Format(PyExc_TypeError,
-                                "'%.200s' object is not a mapping",
-                                arg->ob_type->tp_name);
+                        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,
+                                    "'%.200s' object is not a mapping",
+                                    arg->ob_type->tp_name);
+                        }
                     }
                     Py_DECREF(sum);
                     goto error;

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list