mirror of
https://github.com/python/cpython.git
synced 2026-04-15 00:00:57 +00:00
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:
parent
1af025dd22
commit
6932c3ee6a
11 changed files with 71 additions and 73 deletions
|
|
@ -2416,10 +2416,12 @@ dummy_func(
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
|
||||
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
|
||||
PyObject *dupkey = NULL;
|
||||
|
||||
int err = _PyDict_MergeEx(dict_o, update_o, 2);
|
||||
int err = _PyDict_MergeUniq(dict_o, update_o, &dupkey);
|
||||
if (err < 0) {
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o, dupkey);
|
||||
Py_XDECREF(dupkey);
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
u = update;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
6
Python/executor_cases.c.h
generated
6
Python/executor_cases.c.h
generated
|
|
@ -9458,15 +9458,17 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
|
||||
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
|
||||
PyObject *dupkey = NULL;
|
||||
stack_pointer[0] = update;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int err = _PyDict_MergeEx(dict_o, update_o, 2);
|
||||
int err = _PyDict_MergeUniq(dict_o, update_o, &dupkey);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (err < 0) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o, dupkey);
|
||||
Py_XDECREF(dupkey);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_ERROR();
|
||||
|
|
|
|||
6
Python/generated_cases.c.h
generated
6
Python/generated_cases.c.h
generated
|
|
@ -5605,12 +5605,14 @@
|
|||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
|
||||
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
|
||||
PyObject *dupkey = NULL;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int err = _PyDict_MergeEx(dict_o, update_o, 2);
|
||||
int err = _PyDict_MergeUniq(dict_o, update_o, &dupkey);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (err < 0) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
|
||||
_PyEval_FormatKwargsError(tstate, callable_o, update_o, dupkey);
|
||||
Py_XDECREF(dupkey);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
JUMP_TO_LABEL(error);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue