8000 gh-106672: C API: Report indiscriminately ignored errors by serhiy-storchaka · Pull Request #106674 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

8000 gh-106672: C API: Report indiscriminately ignored errors #106674

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

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update output messsages.
  • Loading branch information
serhiy-storchaka committed Jul 12, 2023
commit 00ce038a31acc88b11b11e33c3fbc3dd0172d28b
22 changes: 18 additions & 4 deletions Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -2431,11 +2431,19 @@ PyMapping_HasKeyString(PyObject *obj, const char *key)
PyObject *dummy;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename to 'item' or 'value'.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int rc = PyMapping_GetOptionalItemString(obj, key, &dummy);
if (rc < 0) {
_PyErr_WriteUnraisableMsg("on testing a mapping key", obj);
_PyErr_WriteUnraisableMsg(
"in PyMapping_HasKeyString(); consider using "
"PyMapping_GetOptionalItemString() or PyMapping_GetItemString()",
NULL);
return 0;
}
// PyMapping_HasKeyString() also clears the error set before it's call
// if the key is not found.
if (rc == 0 && PyErr_Occurred()) {
_PyErr_WriteUnraisableMsg("before testing a mapping key", obj);
_PyErr_WriteUnraisableMsg(
"in PyMapping_HasKeyString(); consider using "
"PyMapping_GetOptionalItemString() or PyMapping_GetItemString()",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is very subtle and the error message is not heplful. It's non-obvious to me that the exception was already set before the function was called.

Maybe the error message should be something like: "Ignore exception set before calling in PyMapping_HasKeyString()".

Instead of "Exception ignored in PyMapping_HasKeyString()".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately _PyErr_WriteUnraisableMsg() does not support this. ☹️

NULL);
return 0;
}
Py_XDECREF(dummy);
Expand All @@ -2448,11 +2456,17 @@ PyMapping_HasKey(PyObject *obj, PyObject *key)
PyObject *dummy;
int rc = PyMapping_GetOptionalItem(obj, key, &dummy);
if (rc < 0) {
_PyErr_WriteUnraisableMsg("on testing a mapping key", obj);
_PyErr_WriteUnraisableMsg(
"in PyMapping_HasKey(); consider using "
"PyMapping_GetOptionalItem() or PyObject_GetItem()", NULL);
return 0;
}
// PyMapping_HasKey() also clears the error set before it's call
// if the key is not found.
if (rc == 0 && PyErr_Occurred()) {
_PyErr_WriteUnraisableMsg("before testing a mapping key", obj);
_PyErr_WriteUnraisableMsg(
"in PyMapping_HasKey(); consider using "
"PyMapping_GetOptionalItem() or PyObject_GetItem()", NULL);
return 0;
}
Py_XDECREF(dummy);
Expand Down
18 changes: 14 additions & 4 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset,
* even if the key is present.
*/
PyObject *
PyDict_GetItem(PyObject *op, PyObject *key)
dict_getitem(PyObject *op, PyObject *key, const char *warnmsg)
{
if (!PyDict_Check(op)) {
return NULL;
Expand All @@ -1673,7 +1673,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) {
hash = PyObject_Hash(key);
if (hash == -1) {
_PyErr_WriteUnraisableMsg("on getting a dict key", op);
_PyErr_WriteUnraisableMsg(warnmsg, NULL);
return NULL;
}
}
Expand All @@ -1696,7 +1696,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
/* Ignore any exception raised by the lookup */
PyObject *exc2 = _PyErr_Occurred(tstate);
if (exc2 && !PyErr_GivenExceptionMatches(exc2, PyExc_KeyError)) {
_PyErr_WriteUnraisableMsg("on getting a dict key", op);
_PyErr_WriteUnraisableMsg(warnmsg, NULL);
}
_PyErr_SetRaisedException(tstate, exc);

Expand All @@ -1705,6 +1705,14 @@ PyDict_GetItem(PyObject *op, PyObject *key)
return value;
}

PyObject *
PyDict_GetItem(PyObject *op, PyObject *key)
{
return dict_getitem(op, key,
"in PyDict_GetItem(); consider using "
"PyDict_GetItemWithError()");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be new PyDict_GetItemRef().

}

Py_ssize_t
_PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
{
Expand Down Expand Up @@ -3893,10 +3901,12 @@ PyDict_GetItemString(PyObject *v, const char *key)
PyObject *kv, *rv;
kv = PyUnicode_FromString(key);
if (kv == NULL) {
_PyErr_WriteUnraisableMsg("on getting a dict key", v);
_PyErr_WriteUnraisableMsg(
"in PyDict_GetItemString()", NULL);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No replacement currently. There will be new PyDict_GetItemRefString().

return NULL;
}
rv = PyDict_GetItem(v, kv);
rv = dict_getitem(v, kv, "in PyDict_GetItemString()");
Py_DECREF(kv);
return rv;
}
Expand Down
9 changes: 7 additions & 2 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,10 @@ PyObject_HasAttrString(PyObject *obj, const char *name)
PyObject *dummy;
int rc = PyObject_GetOptionalAttrString(obj, name, &dummy);
if (rc < 0) {
_PyErr_WriteUnraisableMsg("on testing an object attribute", obj);
_PyErr_WriteUnraisableMsg(
"in PyObject_HasAttrString(); consider using "
"PyObject_GetOptionalAttrString() or PyObject_GetAttrString()",
NULL);
return 0;
}
Py_XDECREF(dummy);
Expand Down Expand Up @@ -1137,7 +1140,9 @@ PyObject_HasAttr(PyObject *obj, PyObject *name)
PyObject *dummy;
int rc = PyObject_GetOptionalAttr(obj, name, &dummy);
if (rc < 0) {
_PyErr_WriteUnraisableMsg("on testing an object attribute", obj);
_PyErr_WriteUnraisableMsg(
"in PyObject_HasAttr(); consider using "
"PyObject_GetOptionalAttr() or PyObject_GetAttr()", NULL);
return 0;
}
Py_XDECREF(dummy);
Expand Down
2 changes: 1 addition & 1 deletion Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ PySys_GetObject(const char *name)
/* XXX Suppress a new exception if it was raised and restore
* the old one. */
if (_PyErr_Occurred(tstate)) {
_PyErr_WriteUnraisableMsg("on getting the sys module attribute", NULL);
_PyErr_WriteUnraisableMsg("in PySys_GetObject()", NULL);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No replacement currently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm waiting until PyDict_GetItemRef() is accepted to consider proposing a variant for PySys_GetObject(). I'm tracking functions returning borrowed references and replacement at: https://pythoncapi.readthedocs.io/bad_api.html#functions

}
_PyErr_SetRaisedException(tstate, exc);
return value;
Expand Down
0