]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-136327: Fix inconsistent ``TypeError`` messages regarding invalid values after...
authorTapeline <mail@tapeline.dev>
Fri, 24 Oct 2025 19:12:49 +0000 (00:12 +0500)
committerGitHub <noreply@github.com>
Fri, 24 Oct 2025 19:12:49 +0000 (19:12 +0000)
Lib/test/pickletester.py
Lib/test/test_extcall.py
Misc/NEWS.d/next/Core_and_Builtins/2025-07-08-00-41-46.gh-issue-136327.7AiTb_.rst [new file with mode: 0644]
Python/ceval.c

index 1a7658b13fa5e3463684318c6d42ddd0da028767..e3663e44546dedcd3f601b69cba5f7d77f735ccf 100644 (file)
@@ -1882,7 +1882,7 @@ class AbstractPicklingErrorTests:
                     with self.assertRaises(TypeError) as cm:
                         self.dumps(obj, proto)
                     self.assertEqual(str(cm.exception),
-                        'functools.partial() argument after ** must be a mapping, not list')
+                        'Value after ** must be a mapping, not list')
                     self.assertEqual(cm.exception.__notes__, [
                         'when serializing test.pickletester.REX object'])
         else:
index d9d85fe79af883f30603baf1f1a527244f582f0e..f003a5837ae0eb23a072336ccca6a81b147e1b15 100644 (file)
@@ -137,7 +137,7 @@ Verify clearing of SF bug #733667
     >>> g(*Nothing())
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.g() argument after * must be an iterable, not Nothing
+    TypeError: Value after * must be an iterable, not Nothing
 
     >>> class Nothing:
     ...     def __len__(self): return 5
@@ -146,7 +146,7 @@ Verify clearing of SF bug #733667
     >>> g(*Nothing())
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.g() argument after * must be an iterable, not Nothing
+    TypeError: Value after * must be an iterable, not Nothing
 
     >>> class Nothing():
     ...     def __len__(self): return 5
@@ -266,7 +266,7 @@ What about willful misconduct?
     >>> h(*h)
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after * must be an iterable, not function
+    TypeError: Value after * must be an iterable, not function
 
     >>> h(1, *h)
     Traceback (most recent call last):
@@ -281,55 +281,53 @@ What about willful misconduct?
     >>> dir(*h)
     Traceback (most recent call last):
       ...
-    TypeError: dir() argument after * must be an iterable, not function
+    TypeError: Value after * must be an iterable, not function
 
     >>> nothing = None
     >>> nothing(*h)
     Traceback (most recent call last):
       ...
-    TypeError: None argument after * must be an iterable, \
-not function
+    TypeError: Value after * must be an iterable, not function
 
     >>> h(**h)
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
+    TypeError: Value after ** must be a mapping, not function
 
     >>> h(**[])
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not list
+    TypeError: Value after ** must be a mapping, not list
 
     >>> h(a=1, **h)
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
+    TypeError: Value after ** must be a mapping, not function
 
     >>> h(a=1, **[])
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not list
+    TypeError: Value after ** must be a mapping, not list
 
     >>> h(**{'a': 1}, **h)
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
+    TypeError: Value after ** must be a mapping, not function
 
     >>> h(**{'a': 1}, **[])
     Traceback (most recent call last):
       ...
-    TypeError: test.test_extcall.h() argument after ** must be a mapping, not list
+    TypeError: Value after ** must be a mapping, not list
 
     >>> dir(**h)
     Traceback (most recent call last):
       ...
-    TypeError: dir() argument after ** must be a mapping, not function
+    TypeError: Value after ** must be a mapping, not function
 
     >>> nothing(**h)
     Traceback (most recent call last):
       ...
-    TypeError: None argument after ** must be a mapping, \
-not function
+    TypeError: Value after ** must be a mapping, not function
 
     >>> dir(b=1, **{'b': 1})
     Traceback (most recent call last):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-07-08-00-41-46.gh-issue-136327.7AiTb_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-07-08-00-41-46.gh-issue-136327.7AiTb_.rst
new file mode 100644 (file)
index 0000000..3798e95
--- /dev/null
@@ -0,0 +1,2 @@
+Errors when calling functions with invalid values after ``*`` and ``**`` now do not
+include the function name. Patch by Ilia Solin.
index defd084db9a4bb4e8ad277654376944a2959a119..7ec5abf5a76bd97ca5e778df39c4de8d3bbe275f 100644 (file)
@@ -3272,17 +3272,9 @@ int
 _Py_Check_ArgsIterable(PyThreadState *tstate, PyObject *func, PyObject *args)
 {
     if (Py_TYPE(args)->tp_iter == NULL && !PySequence_Check(args)) {
-        /* _Py_Check_ArgsIterable() may be called with a live exception:
-         * clear it to prevent calling _PyObject_FunctionStr() with an
-         * exception set. */
-        _PyErr_Clear(tstate);
-        PyObject *funcstr = _PyObject_FunctionStr(func);
-        if (funcstr != NULL) {
-            _PyErr_Format(tstate, PyExc_TypeError,
-                          "%U argument after * must be an iterable, not %.200s",
-                          funcstr, Py_TYPE(args)->tp_name);
-            Py_DECREF(funcstr);
-        }
+        _PyErr_Format(tstate, PyExc_TypeError,
+                      "Value after * must be an iterable, not %.200s",
+                      Py_TYPE(args)->tp_name);
         return -1;
     }
     return 0;
@@ -3298,15 +3290,10 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
      * is not a mapping.
      */
     if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
-        _PyErr_Clear(tstate);
-        PyObject *funcstr = _PyObject_FunctionStr(func);
-        if (funcstr != NULL) {
-            _PyErr_Format(
-                tstate, PyExc_TypeError,
-                "%U argument after ** must be a mapping, not %.200s",
-                funcstr, Py_TYPE(kwargs)->tp_name);
-            Py_DECREF(funcstr);
-        }
+        _PyErr_Format(
+            tstate, PyExc_TypeError,
+            "Value after ** must be a mapping, not %.200s",
+            Py_TYPE(kwargs)->tp_name);
     }
     else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
         PyObject *exc = _PyErr_GetRaisedException(tstate);