gh-136327: Fix inconsistent `TypeError` messages regarding invalid values after * and ** (#136395)
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Errors when calling functions with invalid values after ``*`` and ``**`` now do not
|
||||
include the function name. Patch by Ilia Solin.
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user