bpo-42006: Stop using PyDict_GetItem, PyDict_GetItemString and _PyDict_GetItemId. (GH-22648)
These functions are considered not safe because they suppress all internal errors
and can return wrong result. PyDict_GetItemString and _PyDict_GetItemId can
also silence current exception in rare cases.
Remove no longer used _PyDict_GetItemId.
Add _PyDict_ContainsId and rename _PyDict_Contains into
_PyDict_Contains_KnownHash.
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index ee4ed97..c3ceb78 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -477,10 +477,12 @@ PyModule_GetNameObject(PyObject *m)
}
d = ((PyModuleObject *)m)->md_dict;
if (d == NULL ||
- (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL ||
+ (name = _PyDict_GetItemIdWithError(d, &PyId___name__)) == NULL ||
!PyUnicode_Check(name))
{
- PyErr_SetString(PyExc_SystemError, "nameless module");
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_SystemError, "nameless module");
+ }
return NULL;
}
Py_INCREF(name);
@@ -509,10 +511,12 @@ PyModule_GetFilenameObject(PyObject *m)
}
d = ((PyModuleObject *)m)->md_dict;
if (d == NULL ||
- (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL ||
+ (fileobj = _PyDict_GetItemIdWithError(d, &PyId___file__)) == NULL ||
!PyUnicode_Check(fileobj))
{
- PyErr_SetString(PyExc_SystemError, "module filename missing");
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_SystemError, "module filename missing");
+ }
return NULL;
}
Py_INCREF(fileobj);
@@ -721,14 +725,21 @@ module_getattro(PyModuleObject *m, PyObject *name)
PyErr_Clear();
if (m->md_dict) {
_Py_IDENTIFIER(__getattr__);
- getattr = _PyDict_GetItemId(m->md_dict, &PyId___getattr__);
+ getattr = _PyDict_GetItemIdWithError(m->md_dict, &PyId___getattr__);
if (getattr) {
return PyObject_CallOneArg(getattr, name);
}
- mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__);
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ mod_name = _PyDict_GetItemIdWithError(m->md_dict, &PyId___name__);
if (mod_name && PyUnicode_Check(mod_name)) {
Py_INCREF(mod_name);
- PyObject *spec = _PyDict_GetItemId(m->md_dict, &PyId___spec__);
+ PyObject *spec = _PyDict_GetItemIdWithError(m->md_dict, &PyId___spec__);
+ if (spec == NULL && PyErr_Occurred()) {
+ Py_DECREF(mod_name);
+ return NULL;
+ }
Py_XINCREF(spec);
if (_PyModuleSpec_IsInitializing(spec)) {
PyErr_Format(PyExc_AttributeError,
@@ -746,6 +757,9 @@ module_getattro(PyModuleObject *m, PyObject *name)
Py_DECREF(mod_name);
return NULL;
}
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
}
PyErr_Format(PyExc_AttributeError,
"module has no attribute '%U'", name);