gh-145876: Do not mask KeyErrors raised during dictionary unpacking in call (GH-146472)

KeyErrors raised in keys() or __getitem__() during dictionary unpacking
in call (func(**mymapping)) are no longer masked by TypeError.
This commit is contained in:
Serhiy Storchaka 2026-03-29 11:58:52 +03:00 committed by GitHub
parent 1af025dd22
commit 6932c3ee6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 71 additions and 73 deletions

View file

@ -3456,9 +3456,18 @@ _Py_Check_ArgsIterable(PyThreadState *tstate, PyObject *func, PyObject *args)
}
void
_PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs)
_PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs, PyObject *dupkey)
{
/* _PyDict_MergeEx raises attribute
if (dupkey != NULL) {
PyObject *funcstr = _PyObject_FunctionStr(func);
_PyErr_Format(
tstate, PyExc_TypeError,
"%V got multiple values for keyword argument '%S'",
funcstr, "finction", dupkey);
Py_XDECREF(funcstr);
return;
}
/* _PyDict_MergeUniq raises attribute
* error (percolated from an attempt
* to get 'keys' attribute) instead of
* a type error if its second argument
@ -3478,27 +3487,6 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
_PyErr_ChainExceptions1Tstate(tstate, exc);
}
}
else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *args = PyException_GetArgs(exc);
if (PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1) {
_PyErr_Clear(tstate);
PyObject *funcstr = _PyObject_FunctionStr(func);
if (funcstr != NULL) {
PyObject *key = PyTuple_GET_ITEM(args, 0);
_PyErr_Format(
tstate, PyExc_TypeError,
"%U got multiple values for keyword argument '%S'",
funcstr, key);
Py_DECREF(funcstr);
}
Py_XDECREF(exc);
}
else {
_PyErr_SetRaisedException(tstate, exc);
}
Py_DECREF(args);
}
}
void