-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
gh-146480: Override the exception in _PyErr_SetKeyError() #146486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -248,11 +248,19 @@ PyErr_SetObject(PyObject *exception, PyObject *value) | |
|
|
||
| /* Set a key error with the specified argument, wrapping it in a | ||
| * tuple automatically so that tuple keys are not unpacked as the | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is outdated, because the code no longer explicitly wraps the key in a tuple. But it has roughtly the same effect, the reasons why it does not simply use I wonder if partial reversion of aa36f83 will fix the issue. Would it have performance impact? This is just a curiosity, not suggestion.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated the comment by removing the part about wrapping into a tuple.
The old implementation can be called with an exception set: void
_PyErr_SetKeyError(PyObject *arg)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *tup = PyTuple_Pack(1, arg);
if (!tup) {
/* caller will expect error to be set anyway */
return;
}
_PyErr_SetObject(tstate, PyExc_KeyError, tup);
Py_DECREF(tup);
}
According to my comment, I rewrote |
||
| * exception arguments. */ | ||
| * exception arguments. | ||
| * | ||
| * If an exception is already set, override the exception. */ | ||
| void | ||
| _PyErr_SetKeyError(PyObject *arg) | ||
| { | ||
| PyThreadState *tstate = _PyThreadState_GET(); | ||
|
|
||
| // PyObject_CallOneArg() must not be called with an exception set, | ||
| // otherwise _Py_CheckFunctionResult() can fail if the function returned | ||
| // a result with an excception set. | ||
| _PyErr_Clear(tstate); | ||
|
|
||
| PyObject *exc = PyObject_CallOneArg(PyExc_KeyError, arg); | ||
| if (!exc) { | ||
| /* caller will expect error to be set anyway */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is worth to test also the case when the argument is a tuple and when the argument is a KeyError instance. I think this was the reason of introducing
_PyErr_SetKeyError()instead of simply callingPyErr_SetObject().There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I added tests on a tuple and a KeyError.
Ah right,
PyErr_SetObject(exc_type, value)has an unsual API: if value is a tuple, it unpacks arguments by callingexc_type(*value). Otherwise, it callsexc_type(value).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if the value is already an instance of the specified exception type, it just uses it.